Ant Design Pro 路由及菜单解析
我们先看下官网关于路由和菜单的介绍
路由和菜单是组织起一个应用的关键骨架,pro 中的路由为了方便管理,使用了中心化的方式,在 router.config.js 统一配置和管理。
整个路由和菜单的基本结构如官网所述:
路由管理 通过约定的语法根据在 router.config.js 中配置路由。
菜单生成 根据路由配置来生成菜单。菜单项名称,嵌套路径与路由高度耦合。
面包屑 组件 PageHeader 中内置的面包屑也可由脚手架提供的配置信息自动生成。
路由
目前脚手架中所有的路由都通过 router.config.js 来统一管理,在 umi 的配置中我们增加了一些参数,如 name,icon,hideChildrenInMenu,authority,来辅助生成菜单
菜单
菜单根据 router.config.js 生成,具体逻辑在 src/layouts/BasicLayout 中的 formatter 方法实现
动态菜单
看过Ant Design Pro 2.0的盆友应该知道,整个页面路由的配置都写在文件router.config.js中了,由于是提前配置再加载,所以它是静态的
但往往在我们的实际项目中,都存在需要动态配置路由的情况,比如题主最近在公司做的内部系统项目,就需要针对不同管理权限的人提供不同的菜单路由
在讲解动态菜单生成的具体步骤前,我们先来看下官网对于生成动态菜单方法的介绍
如果你的项目并不需要菜单,你可以直接在 BasicLayout 中删除 SiderMenu 组件的挂载。并在 src/layouts/BasicLayout 中 设置 const MenuData = []。
如果你需要从服务器请求菜单,可以将 menuData 设置为 state,然后通过网络获取来修改了 state。
这句话到底是什么意思了?接下来跟着具体的实例操作一遍,相信大家就明白了
实例介绍
-
在
config/router.config.js
中配置所有页面需要的路由参数 -
在
src/layouts/BasicLayout.js
中连接model与menuData数据
export default connect(({ menuTree, loading, global, setting }) => ({
menuTree, // +
loading: loading.effects['menuTree/getMenu'], // +
collapsed: global.collapsed,
layout: setting.layout,
...setting,
}))(BasicLayout);
请求model中的menuData数据
componentDidMount() {
const { dispatch } = this.props;
// +
dispatch({
type: 'menuTree/getMenu'
})
dispatch({
type: 'user/fetchCurrent',
});
dispatch({
type: 'setting/getSetting',
})
在获取面包屑映射的时候配置states数据
getBreadcrumbNameMap() {
const routerMap = {};
const mergeMenuAndRouter = data => {
data.forEach(menuItem => {
if (menuItem.children) {
mergeMenuAndRouter(menuItem.children);
}
// Reduce memory usage
routerMap[menuItem.path] = menuItem;
});
};
// +
const {menuTree} = this.props
const {menuData} = menuTree
mergeMenuAndRouter(formatter(menuData));
return routerMap;
}
在render中获取到menuData的数据
render() {
const {
menuTree, // +
navTheme,
layout: PropsLayout,
children,
location: { pathname },
} = this.props;
// +
const { isMobile } = this.state;
const {menuData} = menuTree
const menuList = formatter(menuData)
const isTop = PropsLayout === 'topmenu';
const layout = (
<Layout>
{isTop && !isMobile ? null : (
<SiderMenu
logo={logo}
Authorized={Authorized}
theme={navTheme}
onCollapse={this.handleMenuCollapse}
menuData = {menuList} // +
isMobile={isMobile}
{...this.props}
/>
)}
<Layout
style={{
...this.getLayoutStyle(),
minHeight: '100vh',
}}
>
<Header
menuData={menuList} // +
// ......
- 在
src/models/menuTree.js
中更新menuData数据
import { queryMenu } from '@/services/menuTree';
export default {
namespace: 'menuTree',
state: {
menuData: [],
},
effects: {
*getMenu(_, { call, put }) {
const response = yield call(queryMenu);
console.log('response',response)
yield put({
type: 'menuResult',
payload: response[2].routes,
});
},
},
reducers: {
menuResult(state, action) {
return {
...state,
menuData: action.payload,
};
},
},
};
- 在
src/services/menuTree.js
中请求menuData数据
import request from '@/utils/request';
export async function queryMenu() {
return request('/menu/getMenuTree');
}
- 我们使用mock数据来模拟请求的路由参数,在
mock/menu.js
中配置所需要显示的动态路由
export default {
'GET /menu/getMenuTree':[
// user
{
path: '/user',
component: '../layouts/UserLayout',
routes: [
{ path: '/user', redirect: '/user/login' },
{ path: '/user/login', component: './User/Login' },
{ path: '/user/register', component: './User/Register' },
{ path: '/user/register-result', component: './User/RegisterResult' },
],
},
// ......
- 在
src/locales/zh-CN.js
和src/locales/en-US.js
中配置相应路由的显示名称
以上就是Ant Design Pro 动态菜单的所有步骤了